
#ifndef _PIPE_CLIENT_H_
#define _PIPE_CLIENT_H_

#include "talk/base/helpers.h"
#include "talk/base/logging.h"
#include "talk/base/physicalsocketserver.h"
#include "talk/base/ssladapter.h"
#include "talk/xmpp/xmppclientsettings.h"
#include "talk/examples/login/xmppthread.h"
#include "talk/examples/login/xmppauth.h"
#include "talk/p2p/client/httpportallocator.h"
#include "talk/p2p/client/sessionmanagertask.h"
#include "presencepushtask.h"
#include "presenceouttask.h"
//#include "jingleinfotask.h"
#include "talk/session/tunnel/tunnelsessionclient.h"
#include "XMPPCallback.h"
#include "ConnectionCallback.h"
#include "talk/p2p/base/session.h"
#include "talk/session/phone/mediachannel.h"
#include "talk/session/phone/mediamessages.h"
#include "talk/session/phone/call.h"
#include "talk/session/phone/mediasessionclient.h"

#ifndef _CRT_SECURE_NO_DEPRECATE 
#define _CRT_SECURE_NO_DEPRECATE
#endif

struct RosterItem {
  buzz::Jid jid;
  buzz::Status::Show show;
  std::string status;
};


class PipeEp;

class PipeClient : public sigslot::has_slots<>, public talk_base::MessageHandler {
public:
	  enum {
    MSG_STOP,
	MSG_TERMINATE_PIPE,
	MSG_CHECK_PIPE,
  };
	  PipeClient(buzz::XmppClient *xmppclient, XMPPCallback *xc, cricket::MediaEngine* media_engine);
  virtual ~PipeClient();
  void ParseLine(const std::string& line);
  bool ConnectTo(const std::string& remote_jid , ConnectionCallback* cc);
  virtual void OnMessage(talk_base::Message *m);
  cricket::TunnelSessionClient *GetTunnelClient(void) {return tunnel_client_.get();};
  void PrintRoster();
  void SendChat(const std::string& to, const std::string msg);


  cricket::MediaSessionClient* media_client() const { return media_client_; }
  //void SetMediaEngine(cricket::MediaEngine* media_engine) {
   // media_engine_ = media_engine;
  //}

  void SetNick(const std::string& muc_nick);

private:

  typedef std::map<std::string,RosterItem> RosterMap;

  void Reject();
  void Quit();

  void OnStateChange(buzz::XmppEngine::State state);
  void OnRequestSignaling();
  void OnJingleInfo(const std::string & relay_token,
                    const std::vector<std::string> &relay_addresses,
                    const std::vector<talk_base::SocketAddress> &stun_addresses);

  void OnSessionCreate(cricket::Session* session, bool initiate);
  void OnTextChatRecv(const  buzz::Jid  &from, const  buzz::Jid  &to, const std::string &msg);

  const char* DescribeStatus(buzz::Status::Show show, const std::string& desc);

  void OnStatusUpdate(const buzz::Status &status); 
  void OnSignon();
  void OnIncomingTunnel(cricket::TunnelSessionClient* client, buzz::Jid jid,
	  std::string description, cricket::Session* session);
  void ShowPipes(void);
  void RefreshStatus();
  void OnCallCreate(cricket::Call* call);
  void OnCallDestroy(cricket::Call* call);
  void OnMediaSourcesUpdate(cricket::Call* call, cricket::Session* session, const cricket::MediaSources& sources);
  void OnSessionState(cricket::Call* call, cricket::BaseSession* session, cricket::BaseSession::State state);
  void Accept(const cricket::CallOptions& options);

  std::string FindInRoster(std::string jid);

  talk_base::NetworkManager* network_manager_;
  cricket::HttpPortAllocator* port_allocator_;
  talk_base::scoped_ptr<cricket::SessionManager> session_manager_;
  talk_base::scoped_ptr<cricket::TunnelSessionClient> tunnel_client_;
  buzz::XmppClient *xmpp_client_;

  talk_base::Thread *worker_thread_;
  RosterMap* roster_;
  XMPPCallback *xmppCallback_;
  std::vector<PipeEp *> pipes_;

  //cricket::PortAllocator* port_allocator_;
  cricket::SessionManagerTask* session_manager_task_;
  cricket::MediaEngine* media_engine_;
  buzz::PresenceOutTask* presence_out_;
  buzz::Status my_status_;
  cricket::MediaSessionClient* media_client_;
  cricket::Call* call_;
  cricket::BaseSession* session_;
  bool auto_accept_;
  bool incoming_call_;
  uint32 portallocator_flags_;
  bool allow_local_ips_;
  cricket::SignalingProtocol initial_protocol_;
  cricket::SecureMediaPolicy secure_policy_;

};

#endif
